#pragma once

#include "StdAfx.h"

namespace Crypt {

class RC4Engine
{
	uint8 perm[256];
	uint8 index1, index2;
	bool Initialized;

public:

	RC4Engine(const uint8* keybytes, uint32 keylen)
	{
		Setup(keybytes, keylen);
	}

	RC4Engine() : Initialized(false) {}

	~RC4Engine() { }

		void Setup(const uint8* keybytes, const uint32 keylen)
		{
				uint32 i = 0;
				uint8 j = 0, k;

				for(; i < 256; ++i)
						perm[i] = (uint8)i;

				index1 = index2 = 0;

				for(j = 0, i = 0; i < 256; ++i)
				{
						j += perm[i] + keybytes[i % keylen];
						k = perm[i];
						perm[i] = perm[j];
						perm[j] = k;
				}

				Initialized = true;
		}

	void Process(uint8* input, uint8* output, uint32 len)
	{
		uint32 i = 0;
		uint8 j, k;

		for(; i < len; ++i)
		{
			index1++;
			index2 += perm[index1];

			k = perm[index1];
			perm[index1] = perm[index2];
			perm[index2] = k;

			j = perm[index1] + perm[index2];
			output[i] = input[i] ^ perm[j];
		}
	}
};

};